package com.yh.yellowhow;

import java.util.*;

import com.example.yellowhow.*;

import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.*;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.*;

public class ClockView extends View {

	private static final int DEFAULT_VIEW_SIZE = 200;
	private RectF mCircleRect1;
	private RectF mCircleRect2;
	private RectF mCircleRect3;
	private Paint mCirclePaint1;
	private Paint mCirclePaint2;
	private Paint mCirclePaint3;
	private Paint mCircleShadowPaint1;
	private Paint mCircleShadowPaint2;
	private Paint mCircleShadowPaint3;
	private Bitmap mBackground;
	private Calendar c;
	private Runnable r;
	private Handler mHandler;
	private float mCenterWidth;
	private float mCenterHeight;
	private float mCreawHalfWidth;
	private float mCreawHeight;
	private float mMinCreawHalfWidth;
	private float mMinCreawHeight;
	private Path mMinuteScrewPath;
	private Path mHourCrewPath;
	private Paint mHourScrewPaint;
	private Paint mMinuteScrewPaint;
	
	public ClockView(Context context) {
		super(context);
		initialize();
	}
	
	public ClockView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initialize();
	}
	
	public ClockView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initialize();
	}
	
	private void initialize() {
		c = Calendar.getInstance();
		
		mHandler = new Handler();
		r = new Runnable() {
			@Override
			public void run() {
				updateDisplay();
			}
		};
		mHandler.postDelayed(r, 1000); 
		
		initCircle();
	}
	
	protected void updateDisplay() {
		this.invalidate();
		mHandler.postDelayed(r, 1000); 
	}
	

	public interface OnMouseAngleListener {
		void onMouseAngleChanged(View sender, float x, float y, float angle);
	}
	public interface OnMouseStatusListener {
		void onMouseStatu(View sender, String status);
	}
	public interface OnChangeTimeListener {
		void onChangeTime(View sender, int hour, int min);
	}
	
	OnMouseAngleListener onMouseAngleListener = null;
	OnMouseStatusListener onMouseStatusListener = null;
	OnChangeTimeListener onChangeTimeListener = null;
	private Bitmap mScaleBmp;
	
	public void setOnMouseAngleListener(OnMouseAngleListener listener) {
		onMouseAngleListener = listener;
	}
	public void setOnMouseStatusListener(OnMouseStatusListener listener) {
		onMouseStatusListener = listener;
	}
	public void setOnChangeTimeListener(OnChangeTimeListener listener) {
		onChangeTimeListener = listener;
	}
	
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		
		int wMode = MeasureSpec.getMode(widthMeasureSpec);
		int wSize = MeasureSpec.getSize(widthMeasureSpec);
		
		int hMode = MeasureSpec.getMode(heightMeasureSpec);
		int hSize = MeasureSpec.getSize(heightMeasureSpec);
		
		int rWidth = measureSize(wMode, wSize);
		int rHeight = measureSize(hMode, hSize);
		
		int rSize = Math.min(rWidth, rHeight);
		setMeasuredDimension(rSize, rSize);
	}

	private int measureSize(int mode, int size) {
		if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
			return size;
		} else {
			return DEFAULT_VIEW_SIZE;
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		if (mBackground == null)
			return;
		
//		canvas.drawBitmap(mBackground, 0, 0, null);
		
		drawScaleBMP(canvas, mScaleBmp);
		
		drawCreaw(canvas);

	}

	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		updateCreawSize();
		updateScaleSize();
		regenerateBackground();
	}

	private void regenerateBackground() {
		if (mBackground != null) {
			mBackground.recycle();
		}
		
		mBackground = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
		mBackground.eraseColor(0);
		Canvas bcanvas = new Canvas(mBackground);
		
		float scale = (float)getWidth();
		bcanvas.scale(scale, scale);
		
		drawCircle(bcanvas);
	}
	
	private void updateScaleSize() {
		BitmapDrawable bd =
		        (BitmapDrawable)getResources().getDrawable(R.drawable.sun);
		int size = getWidth() / 12;
		mScaleBmp = Bitmap.createScaledBitmap(bd.getBitmap(), size, size, false);
	}
	
	private void updateCreawSize() {
		mCenterWidth = getWidth() / 2;
		mCenterHeight = getHeight() / 2;
		mCreawHalfWidth = getWidth() / 36;
		mCreawHeight = getHeight() / 4;
		mMinCreawHalfWidth = getWidth() / 54;
		mMinCreawHeight = getHeight() / 2.8f;
		
		initCreaw();
	}
	
	private void drawScaleBMP(Canvas canvas, Bitmap bitmap) {
		canvas.save(Canvas.MATRIX_SAVE_FLAG);
		
		float centerBitW = bitmap.getWidth() / 2;
		float centerBitH = bitmap.getHeight() / 2;
		float defaultY = getHeight() / 7;
		float defaultX = mCenterWidth;
		
		for (int i = 0; i < 12; i++) {
			Matrix matrix = new Matrix();
			matrix.preTranslate(-centerBitW, -centerBitH);
			matrix.postRotate(-30 * i);
			matrix.postTranslate(defaultX, defaultY);
			canvas.drawBitmap(bitmap, matrix , null);
			
			canvas.rotate(30, mCenterWidth, mCenterHeight);
		}
		
		canvas.restore();
	}
	
	private void drawCreaw(Canvas canvas) {
		long time = System.currentTimeMillis ();
		c.setTimeInMillis(time);
		int hour = c.get(Calendar.HOUR_OF_DAY);//시간
		int minute = c.get(Calendar.MINUTE);//분
		int second = c.get(Calendar.SECOND); //초
		//c.get(Calendar.MILLISECOND);//밀리 초
		
		
		canvas.save(Canvas.MATRIX_SAVE_FLAG);
		
		canvas.rotate(hour * 30, mCenterWidth, mCenterHeight);
		canvas.drawPath(mHourCrewPath, mHourScrewPaint);
		canvas.restore();
		
		canvas.save(Canvas.MATRIX_SAVE_FLAG);
		canvas.rotate(second * 6, mCenterWidth, mCenterHeight);
		canvas.drawPath(mMinuteScrewPath, mMinuteScrewPaint);
		canvas.restore();
		
		canvas.drawCircle(mCenterWidth, mCenterHeight, 30, mHourScrewPaint);
		canvas.drawCircle(mCenterWidth, mCenterHeight, 25, mMinuteScrewPaint);
	}
	
	private void initCreaw() {
		mMinuteScrewPath = new Path();
		mMinuteScrewPath.moveTo(mCenterWidth,  mCenterHeight - mMinCreawHeight);
		mMinuteScrewPath.lineTo(mCenterWidth + mMinCreawHalfWidth,  mCenterHeight);
		mMinuteScrewPath.lineTo(mCenterWidth - mMinCreawHalfWidth,  mCenterHeight);
		mMinuteScrewPath.lineTo(mCenterWidth,  mCenterHeight - mMinCreawHeight);
		
		mHourCrewPath = new Path();
		mHourCrewPath.moveTo(mCenterWidth,  mCenterHeight - mCreawHeight);
		mHourCrewPath.lineTo(mCenterWidth + mCreawHalfWidth,  mCenterHeight);
		mHourCrewPath.lineTo(mCenterWidth - mCreawHalfWidth,  mCenterHeight);
		mHourCrewPath.lineTo(mCenterWidth,  mCenterHeight - mCreawHeight);
		
		mHourScrewPaint = new Paint();
		mHourScrewPaint.setAntiAlias(true);
		mHourScrewPaint.setColor(Color.rgb(141, 105, 226));
		mHourScrewPaint.setStyle(Paint.Style.FILL);
		
		mMinuteScrewPaint = new Paint();
		mMinuteScrewPaint.setAntiAlias(true);
		mMinuteScrewPaint.setColor(Color.rgb(192, 191, 200));
		mMinuteScrewPaint.setStyle(Paint.Style.FILL);
	}
	
	private void drawCircle(Canvas canvas) {
		canvas.drawOval(mCircleRect3, mCircleShadowPaint3);
		canvas.drawOval(mCircleRect2, mCircleShadowPaint2);
		canvas.drawOval(mCircleRect1, mCircleShadowPaint1);
		canvas.drawOval(mCircleRect1, mCirclePaint1);
		canvas.drawOval(mCircleRect2, mCirclePaint2);
		canvas.drawOval(mCircleRect3, mCirclePaint3);
	}
	
	private void initCircle() {
		mCircleRect1 = new RectF(0.1f, 0.1f, 0.9f, 0.9f);
		mCircleRect2 = new RectF(0.08f, 0.08f, 0.92f, 0.92f);
		mCircleRect3 = new RectF(0.06f, 0.06f, 0.94f, 0.94f);
		
		mCirclePaint1 = new Paint();
		mCirclePaint1.setFlags(Paint.ANTI_ALIAS_FLAG);
		mCirclePaint1.setStyle(Paint.Style.STROKE);
		mCirclePaint1.setColor(Color.BLACK);
		mCirclePaint1.setStrokeWidth(5.0f);
		
		mCirclePaint2 = new Paint(mCirclePaint1);
		mCirclePaint3 = new Paint(mCirclePaint1);
		
		mCircleShadowPaint1 = new Paint();
		mCircleShadowPaint1.setFlags(Paint.ANTI_ALIAS_FLAG);
		mCircleShadowPaint1.setShader(new RadialGradient(0.5f, 0.5f, 0.4f,
				new int[]{Color.rgb(227, 227, 227), Color.rgb(202, 202, 202), Color.rgb(178,178,178)}
		, new float[] {0.95f, 0.9f, 0.99f},
		Shader.TileMode.CLAMP));
		mCircleShadowPaint1.setStyle(Paint.Style.FILL);
		
		mCircleShadowPaint2 = new Paint();
		mCircleShadowPaint2.setFlags(Paint.ANTI_ALIAS_FLAG);
		mCircleShadowPaint2.setShader(new RadialGradient(0.5f, 0.5f, 0.42f,
				new int[]{Color.rgb(227, 227, 227), Color.rgb(202, 202, 202), Color.rgb(178,178,178)}
		, new float[] {0.95f, 0.9f, 0.99f},
		Shader.TileMode.CLAMP));
		mCircleShadowPaint2.setStyle(Paint.Style.FILL);
		
		mCircleShadowPaint3 = new Paint();
		mCircleShadowPaint3.setFlags(Paint.ANTI_ALIAS_FLAG);
		mCircleShadowPaint3.setShader(new RadialGradient(0.5f, 0.5f, 0.44f,
				new int[]{Color.rgb(227, 227, 227), Color.rgb(202, 202, 202), Color.rgb(178,178,178)}
		, new float[] {0.95f, 0.9f, 0.99f},
		Shader.TileMode.CLAMP));
		mCircleShadowPaint3.setStyle(Paint.Style.FILL);
	}
	
}
